package service

import (
	"context"
	"errors"
	"golang.org/x/crypto/bcrypt"
	"time"

	"github.com/example/video_backend/internal/model"
	"github.com/example/video_backend/internal/repository"
)

// AdminService 管理员服务接口
type AdminService interface {
	// Login 管理员登录
	Login(ctx context.Context, username, password string) (*model.User, error)

	// ListUsers 获取用户列表
	ListUsers(ctx context.Context, page, pageSize int) ([]*model.User, int64, error)

	// UpdateUserStatus 更新用户状态
	UpdateUserStatus(ctx context.Context, userID uint, status int) error

	// DeleteUser 删除用户
	DeleteUser(ctx context.Context, userID uint) error

	// ListVideos 获取视频列表
	ListVideos(ctx context.Context, page, pageSize int, filters map[string]interface{}) ([]*model.Video, int64, error)

	// DeleteVideo 删除视频
	DeleteVideo(ctx context.Context, videoID uint) error

	// UpdateVideoStatus 更新视频状态
	UpdateVideoStatus(ctx context.Context, videoID uint, isPublic bool) error

	// ListComments 获取评论列表
	ListComments(ctx context.Context, page, pageSize int, filters map[string]interface{}) ([]*model.Comment, int64, error)

	// DeleteComment 删除评论
	DeleteComment(ctx context.Context, commentID uint) error
}

// adminService 实现AdminService接口
type adminService struct {
	userRepo    repository.UserRepository
	videoRepo   repository.VideoRepository
	commentRepo repository.CommentRepository
}

// NewAdminService 创建管理员服务实例
func NewAdminService(
	userRepo repository.UserRepository,
	videoRepo repository.VideoRepository,
	commentRepo repository.CommentRepository,
) AdminService {
	return &adminService{
		userRepo:    userRepo,
		videoRepo:   videoRepo,
		commentRepo: commentRepo,
	}
}

// Login 管理员登录
func (s *adminService) Login(ctx context.Context, username, password string) (*model.User, error) {
	// 查找用户
	user, err := s.userRepo.GetByUsername(ctx, username)
	if err != nil {
		return nil, err
	}
	if user == nil {
		return nil, errors.New("用户名或密码错误")
	}

	// 检查是否是管理员
	if !user.IsAdmin {
		return nil, errors.New("非管理员用户，无法登录")
	}

	// 检查密码
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
		return nil, errors.New("用户名或密码错误")
	}

	// 更新最后登录时间
	user.LastLoginAt = time.Now()
	if err := s.userRepo.Update(ctx, user); err != nil {
		// 登录成功，更新失败不影响登录
		return user, nil
	}

	return user, nil
}

// ListUsers 获取用户列表
func (s *adminService) ListUsers(ctx context.Context, page, pageSize int) ([]*model.User, int64, error) {
	return s.userRepo.List(ctx, page, pageSize)
}

// UpdateUserStatus 更新用户状态
func (s *adminService) UpdateUserStatus(ctx context.Context, userID uint, status int) error {
	// 查找用户
	user, err := s.userRepo.GetByID(ctx, userID)
	if err != nil {
		return err
	}
	if user == nil {
		return errors.New("用户不存在")
	}

	// 不能修改管理员自身状态
	currentUserID, ok := ctx.Value("userID").(uint)
	if ok && userID == currentUserID && user.IsAdmin {
		return errors.New("不能修改当前管理员账户状态")
	}

	// 更新用户状态
	user.Status = status
	user.UpdatedAt = time.Now()

	return s.userRepo.Update(ctx, user)
}

// DeleteUser 删除用户
func (s *adminService) DeleteUser(ctx context.Context, userID uint) error {
	// 查找用户
	user, err := s.userRepo.GetByID(ctx, userID)
	if err != nil {
		return err
	}
	if user == nil {
		return errors.New("用户不存在")
	}

	// 不能删除管理员账户
	if user.IsAdmin {
		return errors.New("不能删除管理员账户")
	}

	return s.userRepo.Delete(ctx, userID)
}

// ListVideos 获取视频列表
func (s *adminService) ListVideos(ctx context.Context, page, pageSize int, filters map[string]interface{}) ([]*model.Video, int64, error) {
	return s.videoRepo.List(ctx, page, pageSize, filters)
}

// DeleteVideo 删除视频
func (s *adminService) DeleteVideo(ctx context.Context, videoID uint) error {
	return s.videoRepo.Delete(ctx, videoID)
}

// UpdateVideoStatus 更新视频状态
func (s *adminService) UpdateVideoStatus(ctx context.Context, videoID uint, isPublic bool) error {
	// 查找视频
	video, err := s.videoRepo.GetByID(ctx, videoID)
	if err != nil {
		return err
	}
	if video == nil {
		return errors.New("视频不存在")
	}

	// 更新视频状态
	video.IsPublic = isPublic
	video.UpdatedAt = time.Now()

	return s.videoRepo.Update(ctx, video)
}

// ListComments 获取评论列表
func (s *adminService) ListComments(ctx context.Context, page, pageSize int, filters map[string]interface{}) ([]*model.Comment, int64, error) {
	return s.commentRepo.List(ctx, page, pageSize, filters)
}

// DeleteComment 删除评论
func (s *adminService) DeleteComment(ctx context.Context, commentID uint) error {
	return s.commentRepo.Delete(ctx, commentID)
}
